Prisma validator

Chat GPT 4.5 answer

Prisma는 기본적으로 생성된 Model 타입을 제공하지만, 실제 쿼리할 때 사용하는 selectinclude의 결과는 기본 모델 타입과 다르게 구성됩니다. 그래서 기본 모델을 직접 타입으로 사용하면 동적 필드나 관계형 필드가 누락되는 문제가 발생합니다.

이러한 경우는 Prisma가 제공하는 Prisma.validator 및 타입 유틸리티를 이용해 해결하는 것이 가장 좋습니다.

해결 방법

방법 1. Prisma.validator 활용 (권장 방식)

import { Prisma } from '@prisma/client';

const userWithPosts = Prisma.validator<Prisma.UserDefaultArgs>()({
  include: { posts: true },
});

type UserWithPosts = Prisma.UserGetPayload<typeof userWithPosts>;

방법 2. 유틸리티 타입 직접 사용하기

직접 유틸리티 타입을 정의할 수도 있습니다.

import { Prisma } from '@prisma/client';

type UserWithPosts = Prisma.UserGetPayload<{
  include: { posts: true };
}>;

이 방법도 동일한 결과를 제공하지만, 타입이 자주 쓰일 때 재사용하기 좋습니다.


⚙️ 실전 예시

예를 들어 User 모델이 있고, 해당 유저의 postsprofile을 함께 리턴하는 경우라면:

import { PrismaClient, Prisma } from '@prisma/client';

const prisma = new PrismaClient();

const userWithDetails = Prisma.validator<Prisma.UserDefaultArgs>()({
  include: { posts: true, profile: true },
});

type UserWithDetails = Prisma.UserGetPayload<typeof userWithDetails>;

async function getUserWithDetails(userId: number): Promise<UserWithDetails | null> {
  return prisma.user.findUnique({
    where: { id: userId },
    include: { posts: true, profile: true },
  });
}

이렇게 하면 UserWithDetails는 정확하게 다음과 같은 타입을 갖게 됩니다:

type UserWithDetails = {
  id: number;
  email: string;
  name: string | null;
  posts: Post[];    // posts 모델 배열 포함
  profile: Profile | null; // profile 모델 포함
};

📌 장점

이 방법을 적극적으로 활용하면 Prisma의 모델 타입 재활용 시 타입 정보 손실 문제를 깔끔하게 해결할 수 있습니다.